package dog.gui.appointmentView;

import javax.swing.*;
import javax.swing.event.ListDataEvent;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

import constants.CHANGE;
import containers.Appointment;
import containers.Room;
import dog.gui.RoomCellRenderer;
import dog.model.Model;

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

@SuppressWarnings("serial")
public class AppointmentInfoPanel extends JPanel implements ActionListener, FocusListener, KeyListener, PropertyChangeListener{
	
	private JTextField titleField;
	private JTextField locationField;
	private JTextField timeStartField;
	private JTextField timeEndField;
	private JComboBox roomBox;
	private JTextArea descriptionField;
	
	private Appointment oldAppointment = null;
	private Appointment newAppointment = null;
	private Model model;
	private boolean generatedPopup=false;
	
	public AppointmentInfoPanel(AppointmentPanel parent, Model model){
		super();
		this.model=model;
		model.addPropertyChangeListener(this);
		GridBagLayout layout = new GridBagLayout();
		setLayout(layout);
		GridBagConstraints GridBagItem = new GridBagConstraints();
		GridBagItem.insets = new Insets(2, 10, 2, 1);
		GridBagItem.fill = GridBagConstraints.VERTICAL;
		GridBagItem.anchor=GridBagConstraints.WEST;
		
		JLabel label;
		
		GridBagItem.gridwidth=1;
		label = new JLabel("Title:");
		GridBagItem.gridx = 0;
		GridBagItem.gridy = 0;
		add(label, GridBagItem);
		
		GridBagItem.gridwidth=3;
		titleField = new JTextField("Subject");
		GridBagItem.gridx = 1;
		GridBagItem.gridy = 0;
		titleField.setColumns(10);
		add(titleField, GridBagItem);
		titleField.addFocusListener(this);
		titleField.addActionListener(this);
		
		GridBagItem.gridwidth=1;
		label = new JLabel ("From Time:");
		GridBagItem.gridx = 0;
		GridBagItem.gridy = 1;
		add(label, GridBagItem);
		
		GridBagItem.gridwidth=1;
		timeStartField = new JTextField("DD/MM-YYYY,hh:mm");
		GridBagItem.gridx = 1;
		GridBagItem.gridy = 1;
		GridBagItem.gridwidth=2;
		timeStartField.setColumns(12);
		add(timeStartField, GridBagItem);
		timeStartField.addFocusListener(this);
		timeStartField.addActionListener(this);
		
		GridBagItem.gridwidth=1;
		label = new JLabel ("To Time");
		GridBagItem.gridx = 0;
		GridBagItem.gridy = 2;
		add(label, GridBagItem);
		
		GridBagItem.gridwidth=1;
		timeEndField = new JTextField("DD/MM-YYYY,hh:mm");
		GridBagItem.gridx = 1;
		GridBagItem.gridy = 2;
		timeEndField.setColumns(12);
		add(timeEndField, GridBagItem);
		timeEndField.addFocusListener(this);
		timeEndField.addActionListener(this);

		label = new JLabel ("Room:");
		GridBagItem.gridx = 0;
		GridBagItem.gridy = 3;
		add(label, GridBagItem);
		roomBox = new JComboBox();
		GridBagItem.gridx = 1;
		GridBagItem.gridy = 3;
		GridBagItem.anchor = GridBagConstraints.WEST;
		roomBox.setModel(new DefaultComboBoxModel());
		roomBox.setPrototypeDisplayValue(new Room(-1,"Aaaaaaaaaaaaaaaa aa",-1));
		roomBox.setRenderer(new RoomCellRenderer());
		((DefaultComboBoxModel)roomBox.getModel()).addElement(new Room(-1,"No room",0));
		Room[] curr = model.gui_getCurrentRooms();
		for(int i=0; i<curr.length; i++)
			{
			((DefaultComboBoxModel)roomBox.getModel()).addElement(curr[i]);
			}
		add(roomBox, GridBagItem);
		roomBox.addActionListener(this);
		roomBox.addPopupMenuListener(new PopupMenuListener()
			{	public void popupMenuCanceled(PopupMenuEvent arg0)
					{}
				public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0)
					{}
				public void popupMenuWillBecomeVisible(PopupMenuEvent arg0)
					{if(!generatedPopup)
					{setStartTime();
					setEndTime();
					System.out.println("Popup");
					refreshRoomAvailabilities();}
					generatedPopup=false;}});
		
		
		GridBagItem.gridwidth=4;
		label = new JLabel("Location:");
		GridBagItem.gridx = 0;
		GridBagItem.gridy = 4;
		add(label, GridBagItem);
		
		GridBagItem.gridwidth=1;
		locationField = new JTextField("");
		GridBagItem.gridx = 1;
		GridBagItem.gridy = 4;
		GridBagItem.gridwidth=2;
		locationField.setColumns(12);
		add(locationField, GridBagItem);
		locationField.addFocusListener(this);
		locationField.addActionListener(this);
		
		
		GridBagItem.gridwidth=4;
		label = new JLabel("Description:");
		GridBagItem.gridx = 0;
		GridBagItem.gridy = 5;
		add(label, GridBagItem);
		
		GridBagItem.gridwidth=4;
		descriptionField = new JTextArea("");
		GridBagItem.gridx = 0;
		GridBagItem.gridy = 6;
		descriptionField.setLineWrap(true);
		descriptionField.setColumns(25);
		descriptionField.setRows(6);
		add(descriptionField, GridBagItem);
		descriptionField.addFocusListener(this);
		descriptionField.addKeyListener(this);
		
		setEditable(true);

	}
	public void refreshRoomAvailabilities()
		{
		if (newAppointment.startTime!=null && newAppointment.endTime!=null)
			{
			int exceptOwner=-1;
			int exceptAppointment=-1;
			if(oldAppointment!=null)
				{
				exceptOwner=oldAppointment.ownerPersonID;
				exceptAppointment=oldAppointment.appointmentID;
				}
			model.gui_updateRoomAvailabilities(newAppointment.startTime, newAppointment.endTime,exceptOwner,exceptAppointment);
			}
		}
	public void setEditable(boolean editable)
		{
		titleField.setEnabled(editable);
		timeStartField.setEnabled(editable);
		timeEndField.setEnabled(editable);
		descriptionField.setEnabled(editable);
		roomBox.setEnabled(editable);
		if (roomBox.getSelectedIndex()<=0)//If no room
			locationField.setEnabled(editable);
		else
			locationField.setEnabled(false);
		}
	
	public void updateToAppointment(Appointment oldAppointment,Appointment newAppointment){
		this.newAppointment=newAppointment;
		this.oldAppointment=oldAppointment;
		if(oldAppointment!=null){
			titleField.setText(oldAppointment.subject);
			timeStartField.setText(model.formatTime(oldAppointment.startTime));
			timeEndField.setText(model.formatTime(oldAppointment.endTime));
			if(oldAppointment.roomID==-1)
				roomBox.setSelectedItem(0);
			else
				roomBox.setSelectedItem(model.getRoom(oldAppointment.roomID));
			descriptionField.setText(oldAppointment.description);
			System.out.println("Description is "+oldAppointment.description);
			locationField.setText(oldAppointment.locationName);
		}
		
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {
		if (arg0.getSource() == titleField){
			newAppointment.subject=titleField.getText();
		}
		else if (arg0.getSource() == locationField){
			newAppointment.locationName=locationField.getText();
		}
		else if (arg0.getSource() == timeStartField){
			{
			try{newAppointment.startTime=model.toTimestamp(timeStartField.getText());}
			catch (Exception e){newAppointment.startTime=null;
			JOptionPane.showMessageDialog(null, "Wrong format, use DD/MM-YYYY,hh:mm","Error",JOptionPane.ERROR_MESSAGE);}
			}
		}
		else if (arg0.getSource() == timeEndField){
			{
			try{newAppointment.endTime=model.toTimestamp(timeEndField.getText());}
			catch (Exception e){newAppointment.endTime=null;
			JOptionPane.showMessageDialog(null, "Wrong format, use DD/MM-YYYY,hh:mm","Error",JOptionPane.ERROR_MESSAGE);}
			}
		}
		else if (arg0.getSource().equals(roomBox)) {
			newAppointment.roomID=((Room) roomBox.getSelectedItem()).roomID;
			locationField.setEnabled((newAppointment.roomID==-1));
		}
	}
	
	@Override
	public void focusGained(FocusEvent arg0) {
		if (arg0.getSource().equals(titleField)) {
			if (titleField.getText().equals("title of appointment")) {
				titleField.setText("");
			}
		}
		else if (arg0.getSource().equals(locationField)) {
			if (locationField.getText().equals("location of appointment")) {
				locationField.setText("");
			}
		}
		else if (arg0.getSource().equals(timeStartField)) {
			if (timeStartField.getText().equals("DD/MM-YYYY,hh:mm")) {
				timeStartField.setText("");
			}
		}
		else if (arg0.getSource().equals(timeEndField)) {
			if (timeEndField.getText().equals("DD/MM-YYYY,hh:mm")) {
				timeEndField.setText("");
			}
		}
	}
	
	@Override
	public void focusLost(FocusEvent arg0) {
		if (arg0.getSource().equals(titleField)) {
			if (titleField.getText().isEmpty()) 
				titleField.setText("title of appointment");
			else
				newAppointment.subject=titleField.getText();
		} 
		else if (arg0.getSource().equals(locationField)) {
			if (locationField.getText().isEmpty()) 
				locationField.setText("location of appointment");
			else
				newAppointment.locationName=locationField.getText();
		} 
		else if (arg0.getSource().equals(timeStartField)) {
			setStartTime();
		}
		else if (arg0.getSource().equals(timeEndField)) {
			setEndTime();
		}
	}

	private void setStartTime()
		{
		if (timeStartField.getText().isEmpty()) 
			{
			timeStartField.setText("DD/MM-YYYY,hh:mm");
			}
		else
			{
			try{newAppointment.startTime=model.toTimestamp(timeStartField.getText());}
			catch (Exception e){newAppointment.startTime=null;
			JOptionPane.showMessageDialog(null, "Wrong format, use DD/MM-YYYY,hh:mm","Error",JOptionPane.ERROR_MESSAGE);}
			}
		}
	private void setEndTime()
		{
		if (timeEndField.getText().isEmpty()) 
			{
			timeEndField.setText("DD/MM-YYYY,hh:mm");
			}
		else
			{
			try{newAppointment.endTime=model.toTimestamp(timeEndField.getText());}
			catch (Exception e){newAppointment.endTime=null;
			JOptionPane.showMessageDialog(null, "Wrong format, use DD/MM-YYYY,hh:mm","Error",JOptionPane.ERROR_MESSAGE);}
			}
		}
	@Override
	public void keyPressed(KeyEvent arg0) 
		{}

	@Override
	public void keyReleased(KeyEvent e) {
		if(e.getSource() == descriptionField){
			{
			newAppointment.description=descriptionField.getText();
			}
		}
		
	}

	@Override
	public void keyTyped(KeyEvent e) 
		{}
	@Override
	public void propertyChange(PropertyChangeEvent e)
		{
		String type = e.getPropertyName();
		if (type.equals(CHANGE.ROOM_AVAILABILITY))
			{
			System.out.println("Box repaint");
			roomBox.setRenderer(new RoomCellRenderer());
			generatedPopup=true;
			roomBox.showPopup();
			//roomBox.contentsChanged(new ListDataEvent(this,ListDataEvent.CONTENTS_CHANGED,0,((DefaultComboBoxModel)roomBox.getModel()).getSize()-1));
			}
		else if (type.equals(CHANGE.ROOM))
			{	
			Room old = (Room)e.getOldValue();
			Room room = (Room)e.getNewValue();
			DefaultComboBoxModel boxModel = (DefaultComboBoxModel)roomBox.getModel();
			if (old!=null)
				boxModel.removeElement(old);
			if (room!=null)
				boxModel.addElement(room);
			repaint();
			}
		}
	}
